package com.sc.nft.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.sc.nft.dao.BoxItemDao;
import com.sc.nft.dao.ProductStockDao;
import com.sc.nft.dao.UserInfoDao;
import com.sc.nft.entity.*;
import com.sc.nft.service.UserInfoService;
import com.sc.nft.util.RedisUtil;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import com.sc.nft.service.BoxItemService;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 盲盒子项表服务接口实现
 *
 * @author zxy
 * @since 2022-06-03 01:43:54
 * @description 由 Mybatisplus Code Generator 创建
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class BoxItemServiceImpl implements BoxItemService {
    private final BoxItemDao boxItemDao;
    private final ProductStockDao productStockDao;
    private final UserInfoDao userInfoDao;
    private final RedisUtil redisUtil;

    @Override
    public BoxItem openBox(Long productId,Long boxId) {
        List<ProductStock> stocks = productStockDao.getBoxItemStock(productId,boxId);
        if(stocks.size() == 1){
            return boxItemDao.getById(stocks.get(0).getItemId());
        }
        int sum = stocks.stream().mapToInt(ProductStock::getUsableCount).sum();
        Map<Long,IndexRange> map = Maps.newHashMap();
        int idx=0;

        for (ProductStock stock : stocks) {
            map.put(stock.getItemId(),new IndexRange(idx+1,idx+stock.getUsableCount()));
            idx+=stock.getUsableCount();
        }
        int  result = RandomUtil.randomInt(1,sum);
        for (Map.Entry<Long, IndexRange> entrty : map.entrySet()) {
            IndexRange indexRange = entrty.getValue();
            if(indexRange.min<=result&&indexRange.max>=result){
                return boxItemDao.getById(entrty.getKey());
            }
        }
        return null;
    }

    @Override
    public BoxItem openBoxByInvite(Long productId, Long boxId,Long userId) {
        List<ProductStock> stocks = productStockDao.getBoxItemStock(productId,boxId);
        if(stocks.size() == 1){
            return boxItemDao.getById(stocks.get(0).getItemId());
        }
        int sum = stocks.stream().mapToInt(ProductStock::getUsableCount).sum();
        Map<Long,IndexRange> map = Maps.newHashMap();
        int idx=0;
        for (ProductStock stock : stocks) {
            map.put(stock.getItemId(),new IndexRange(idx+1,idx+stock.getUsableCount()));
            idx+=stock.getUsableCount();
        }
        int result = RandomUtil.randomInt(1,sum);
        //藏品列表
        ArrayList<Long> collectionList = getCollectionList();
        //团队列表
        List<String> userTeamList = getUserTeamList();

        for (Map.Entry<Long, IndexRange> entrty : map.entrySet()) {
            IndexRange indexRange = entrty.getValue();
            if(indexRange.min<=result&&indexRange.max>=result){
                Long collectionId =  boxItemDao.getById(entrty.getKey()).getCollectionId();
                if(!collectionList.contains(collectionId) && userTeamList.contains(userId.toString())){
                    return openBox(productId,boxId);
                }
                return boxItemDao.getById(entrty.getKey());
            }
        }
        return null;
    }

    @Override
    public BoxItem openBoxByInviteProbability(Long productId, Long boxId, Long userId) {
        List<ProductStock> stocks = productStockDao.getBoxItemStock(productId,boxId);
        if(stocks.size() == 1){
            return boxItemDao.getById(stocks.get(0).getItemId());
        }
        int sum = stocks.stream().mapToInt(ProductStock::getUsableCount).sum();
        Map<Long,IndexRange> map = Maps.newHashMap();
        int idx=0;
        for (ProductStock stock : stocks) {
            map.put(stock.getItemId(),new IndexRange(idx+1,idx+stock.getUsableCount()));
            idx+=stock.getUsableCount();
        }
        int result = RandomUtil.randomInt(1,sum);
        //藏品列表
        ArrayList<Long> collectionList = getCollectionList();
        //团队列表
        List<String> userTeamList = getUserTeamList();

        for (Map.Entry<Long, IndexRange> entrty : map.entrySet()) {
            IndexRange indexRange = entrty.getValue();
            if(indexRange.min<=result&&indexRange.max>=result){
                Long collectionId =  boxItemDao.getById(entrty.getKey()).getCollectionId();
                if(!collectionList.contains(collectionId) && userTeamList.contains(userId.toString())){
                    return openBoxByInvite(productId,boxId,userId);
                }
                return boxItemDao.getById(entrty.getKey());
            }
        }
        return null;
    }


    private List<String> getUserTeamList(){
        Object teamBy142 = redisUtil.lGet("teamBy142",0,-1);
        if(ObjectUtil.isNotEmpty(teamBy142)){
            return  (List<String>)teamBy142;
        }


        List<UserInfo> list =getTeamOwnerList(142L);
        ArrayList<String> ids = new ArrayList<>();
        for (UserInfo userInfo : list) {
            Long userInfoId = userInfo.getId();
            ids.add(userInfoId.toString());
            redisUtil.lPush("teamBy142", userInfoId.toString());
        }
        redisUtil.expire("teamBy142",30);
        return ids;
    }
    private ArrayList<Long> getCollectionList(){
        ArrayList<Long> collection = new ArrayList<>();
        collection.add(58L);
        collection.add(59L);
        collection.add(60L);
        return collection;
    }

    List<UserInfo> getTeamOwnerList(Long userId){

        UserInfo userInfo = userInfoDao.getById(userId);
        List<UserInfo> list = new ArrayList<>();

        String recommendUserId = userInfo.getId().toString();

        List<UserInfo> userInfos = userInfoDao.getTeamOwnerList(recommendUserId);
        if(userInfos.size() > 0){
            list.addAll(userInfos);
            for (UserInfo info : userInfos) {
                recommendUserId = info.getId().toString();
                while (true){
                    List<UserInfo> teamOwnerList = userInfoDao.getTeamOwnerList(recommendUserId);
                    if(teamOwnerList.size() > 0){
                        list.addAll(teamOwnerList);
                        String ids = "";
                        for (UserInfo teamOwner : teamOwnerList) {
                            ids = ids + teamOwner.getId() + ",";
                        }
                        recommendUserId = ids.substring(0, ids.length() - 1);
                    }else{
                        break;
                    }
                }
            }
        }

        return list;
    }


    @AllArgsConstructor
    class IndexRange{
        private int min;
        private int max;
    }


}